package com.ruoyi.web.controller.cpsp;
/*
    @author neu.xiangwenjuan
    @create 2022/4/15
*/

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.cpsp.dto.ApprovalRecordModifyDto;
import com.ruoyi.cpsp.mapper.*;
import com.ruoyi.cpsp.domain.*;
import com.ruoyi.cpsp.service.*;
import com.ruoyi.system.service.ISysDeptService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@CrossOrigin
@RestController
@RequestMapping("/cpsp/evaluateRecordDetail")
public class EvaluateRecordDetailController {

    @Autowired
    private EvaluateRecordMapper evaluateRecordMapper;

    @Autowired
    private RegulationTimesMapper regulationTimesMapper;

    @Autowired
    private EvaluateRecordToEmployeeMapper toEmployeeMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private TeamGroupMapper teamGroupMapper;

    @Autowired
    private EvaluateRecordDetailService detailService;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private EvaluateRecordService evaluateRecordService;

    @Autowired
    private ISysDeptService iSysDeptService;

    @Autowired
    private EvaluateRecordToEmployeeService toEmployeeService;

    @Autowired
    private RegulationDetailAndTimesService timesService;

    @Autowired
    private ApprovalRecordService approvalRecordService;

    @Autowired
    private CurrentPerformanceDataService currentPerformanceDataService;

    private EmployeeController employeeController = new EmployeeController();

    @ApiOperation("获得每次违章肇事者的详细记录")
    @RequestMapping(value = "/getEvaluateDetail", method = RequestMethod.GET)
    @ResponseBody
    private AjaxResult getEvaluateDetail(@RequestParam(defaultValue = "1") Integer pageNum,
                                     @RequestParam(defaultValue = "10") Integer pageSize) {
        List<EvaluateRecordDetailEn> list = new ArrayList<>();
        PageHelper.startPage(pageNum,pageSize);
        list = detailService.selectAllDetail(null);
        PageInfo pageInfo = PageInfo.of(list);
        return AjaxResult.success(pageInfo);
    }

    /**
     * 根据name或者idCard模糊查询某个员工的违章记录。
     * @param employeeInfo
     * @return
     */
    @ApiOperation("获得某个员工的详细违章记录")
    @RequestMapping(value = "/getDetailByEmployee", method = RequestMethod.GET)
    @ResponseBody
    private AjaxResult getDetailByEmployee(String employeeInfo) {
        List<EvaluateRecordDetailEn> employeeList = detailService.selectDetailByEmployee(employeeInfo);
        if (employeeList.size() > 0) {
            return AjaxResult.success(employeeList);
        }else {
            List<EmployeeEntity> employees = employeeService.selectByName(employeeInfo, 0);
            for (EmployeeEntity employee:employees) {
                List<EvaluateRecordDetailEn> list = detailService.selectDetailByEmployee(employee.getIdCard());
                employeeList.addAll(list);
            }
            return AjaxResult.success(employeeList);
        }
    }

    /**
     * 添加开始时间、结束时间筛选项。类型是YYYY-MM-dd HH:mm:ss
     * @param pageNum
     * @param pageSize
     * @param department
     * @param teamGroup
     * @return
     */
    @ApiOperation("根据部门或班组筛选违章记录")
    @RequestMapping(value = "/getDetailByDepart", method = RequestMethod.GET)
    @ResponseBody
    private AjaxResult getDetailByDepart(@RequestParam(defaultValue = "1") Integer pageNum,
                                     @RequestParam(defaultValue = "10") Integer pageSize,
                                     @RequestParam(required = false) String department,
                                     @RequestParam(required = false) String teamGroup,
                                     @RequestParam(required = false) String startTime,
                                     @RequestParam(required = false) String endTime) {
        if (startTime == null) {// 当前季度第一天。
            startTime = getQuarterStart(new Date());
        }
        if (endTime == null) {// 当前季度最后一天。
            endTime = getQuarterEnd(new Date());
        }
        if (department == null || department.equals("null")) {
            department = "";
        }
        if (teamGroup == null || teamGroup.equals("null")) {
            teamGroup = "";
        }
        PageHelper.startPage(pageNum,pageSize);
        List<EvaluateRecordDetailEn> list = detailService.selectByDepart(department, teamGroup, startTime, endTime);
        PageInfo pageInfo = PageInfo.of(list);
        return AjaxResult.success(pageInfo);
    }


    @ApiOperation("添加违章记录")
    @RequestMapping(value = "/insertDetail", method = RequestMethod.POST)
    @ResponseBody
    private AjaxResult insertDetail(@RequestParam String employeeIdCard,
                                    @RequestParam Integer regulationTypeId,
                                    @RequestParam Integer regulationDetailId,
                                    @RequestParam Integer year,
                                    @RequestParam Integer session,
                                    @RequestParam String datetime) {
        EvaluateRecordDetail evaluateRecordDetail = new EvaluateRecordDetail();
        EmployeeEntity employee = employeeService.selectByCard(employeeIdCard);
        evaluateRecordDetail.setYear(year);
        evaluateRecordDetail.setQuarter(session);
        evaluateRecordDetail.setEmployeeIdCard(employeeIdCard);
        evaluateRecordDetail.setEmployeeDepart(employee.getDepartment().getDepartmentId());

        evaluateRecordDetail.setRegulationTypeId(regulationTypeId);
        evaluateRecordDetail.setRegulationDetailId(regulationDetailId);
        evaluateRecordDetail.setDateTime(datetime);
        evaluateRecordDetail.setState(1);
        if (employee.getTeamGroup() == null) {
            evaluateRecordDetail.setEmployeeGroup(0);
        }else {
            evaluateRecordDetail.setEmployeeGroup(employee.getTeamGroup().getId());
        }
        int tag = detailService.insertDetail(evaluateRecordDetail);
        if (tag < 1) {
            return AjaxResult.error("插入数据失败！");
        }
        // 插入到detail表之后，需要将相应的信息添加到evaluate_record表中，保存统计出来的信息，并根据违章次数来添加关联人员。
        // 调用evaluate_record表中的插入语句。
        evaluateRecordService.insertEvaluateRecord(evaluateRecordDetail);
        //TODO 添加一条违章记录后需要更新current_performance_data表中对应关联人的信息。这个方法可以仿照导出绩效信息的接口
        return AjaxResult.success("插入数据成功！");
    }


    @ApiOperation("删除违章记录")
    @RequestMapping(value = "/deleteDetail", method = RequestMethod.POST)
    @ResponseBody
    private AjaxResult deleteDetail(Integer id) {
        // 如果用户角色为部门则提交申请，管理员则直接处理。
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();
        String role = sysUser.getRoles().get(0).getRoleKey();
        SysDept dept = iSysDeptService.selectDeptById(sysUser.getDeptId());
        String departmentId = dept.getDepartmentId();
        EvaluateRecordDetail detail = detailService.selectByPrimaryKey(id);
        if (role.equals("department")) {
            ApprovalRecordModifyDto approvalRecordModifyDto = new ApprovalRecordModifyDto();
            approvalRecordModifyDto.setApplyPersonId(sysUser.getUserId().intValue());
            approvalRecordModifyDto.setApplyPersonName(sysUser.getUserName());
            approvalRecordModifyDto.setDetailId(id);
            approvalRecordModifyDto.setApplyPersonDeptId(departmentId);
            approvalRecordModifyDto.setApplyPersonDept(dept.getDeptName());
            approvalRecordModifyDto.setViolationPersonName(employeeService.selectByCard(detail.getEmployeeIdCard()).getName());
            approvalRecordModifyDto.setOperateType(0);
            approvalRecordModifyDto.setState(0);
            int flag = approvalRecordService.insert(approvalRecordModifyDto);
            // 更新违章记录状态。
            detail.setState(0);
            int tag = detailService.updateByIdSelective(detail);
            if (flag > 0 && tag > 0) {
                return AjaxResult.success("添加申请成功！");
            }else {
                return AjaxResult.error("添加申请失败！");
            }

        }else if (role.equals("admin") || role.equals("sysadmin") || role.equals("supervision")){
            return deleteDetailUtil(id);
        }
        return AjaxResult.success("此类型用户不能进行删除！");
    }

    /**
     *
     * @param id  根据违章id获得违章信息。
     * @return
     */
    @ApiOperation("点击修改按钮后，得到该违章的信息")
    @RequestMapping(value = "/getUpdateBeforeDetail", method = RequestMethod.GET)
    @ResponseBody
    private AjaxResult getUpdateBeforeDetail(Integer id){
        EvaluateRecordDetailEn recordDetail = detailService.selectDetailById(id);
        if (recordDetail != null) {
            return AjaxResult.success(recordDetail);
        }else {
            return AjaxResult.error("获取失败！");
        }
    }

    /**
     *
     *
     * @param detailId   与上面获得违章信息的id一致。
     * @param employeeIdCard  选择的新的员工的身份证号
     * @param regulationTypeId  选择的新的违章类型id
     * @param regulationDetailId  选择的新的违章细节id
     * @return
     */
    @ApiOperation("更新违章记录")
    @RequestMapping(value = "/updateEvaluateDetail", method = RequestMethod.POST)
    @ResponseBody
    private AjaxResult updateEvaluateDetail(@RequestParam Integer detailId,
                                        @RequestParam Integer year,
                                        @RequestParam Integer quarter,
                                        @RequestParam String employeeIdCard,
                                        @RequestParam Integer regulationTypeId,
                                        @RequestParam Integer regulationDetailId) {

        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();
        String role = sysUser.getRoles().get(0).getRoleKey();
        SysDept dept = iSysDeptService.selectDeptById(sysUser.getDeptId());
        String departmentId = dept.getDepartmentId();
        EvaluateRecordDetail detail = detailService.selectByPrimaryKey(detailId);
        if (role.equals("department")) {
            ApprovalRecordModifyDto approvalRecordModifyDto = new ApprovalRecordModifyDto();
            approvalRecordModifyDto.setApplyPersonId(sysUser.getUserId().intValue());
            approvalRecordModifyDto.setApplyPersonName(sysUser.getUserName());
            approvalRecordModifyDto.setDetailId(detailId);
            approvalRecordModifyDto.setApplyPersonDeptId(departmentId);
            approvalRecordModifyDto.setApplyPersonDept(dept.getDeptName());
            approvalRecordModifyDto.setViolationPersonName(employeeService.selectByCard(detail.getEmployeeIdCard()).getName());
            approvalRecordModifyDto.setOperateType(1);
            approvalRecordModifyDto.setEmployeeIdCard(employeeIdCard);
            approvalRecordModifyDto.setRegulationTypeId(regulationTypeId);
            approvalRecordModifyDto.setRegulationDetailId(regulationDetailId);
            approvalRecordModifyDto.setState(0);
            int flag = approvalRecordService.insert(approvalRecordModifyDto);
            // 更新违章记录状态。
            detail.setState(0);
            int tag = detailService.updateByIdSelective(detail);
            if (flag > 0 && tag > 0) {
                return AjaxResult.success("添加申请成功！");
            }else {
                return AjaxResult.error("添加申请失败！");
            }
        }
        else if (role.equals("admin") || role.equals("sysadmin") || role.equals("supervision")) {
            return updateDetailUtil(detailId, employeeIdCard, regulationTypeId, regulationDetailId);
        }else {
            return AjaxResult.success("此类型用户不能进行编辑！");
        }
    }

    public AjaxResult updateDetailUtil(Integer detailId,
                                       String employeeIdCard,
                                       Integer regulationTypeId,
                                       Integer regulationDetailId) {
        if (detailService.selectDetailById(detailId) != null && employeeIdCard != null && regulationTypeId != null && regulationDetailId != null) {
            // 先根据违章id删除该违章记录。
            EvaluateRecordDetailEn evaluateRecordDetail = detailService.selectDetailById(detailId);
            AjaxResult ajaxResult = deleteDetailUtil(detailId);
            if (!ajaxResult.containsValue(200)) {
                return AjaxResult.error("删除记录失败！");
            }
            // 再根据身份证号，违章类型id，违章细节id重新添加。
            AjaxResult AjaxResult1 = insertDetail(employeeIdCard,regulationTypeId,regulationDetailId,evaluateRecordDetail.getYear(), evaluateRecordDetail.getQuarter(), evaluateRecordDetail.getDateTime());
            System.out.println("+++++++++++++++++++"+regulationTypeId+"+++++++++++++++++++"+regulationDetailId+"+++++++++++++++++++");
            if (!AjaxResult1.containsValue(200)) {
                return AjaxResult.error("添加更新后记录失败！");
            }
            return AjaxResult.success("更新违章记录成功！");
        }else {
            return AjaxResult.error("参数不符合要求！");
        }

    }
    public AjaxResult deleteDetailUtil(Integer detailId) {
        EvaluateRecordDetail detail = detailService.selectByPrimaryKey(detailId);
        Integer teamGroupId = detail.getEmployeeGroup();
        TeamGroup teamGroup = teamGroupMapper.selectById(teamGroupId);
        boolean isManageTag =  teamGroup != null && teamGroup.getTeamGroupName().contains("管理");
        int year = detail.getYear();
        int session = detail.getQuarter();
        System.out.println(session);
        // 查找evaluate_record表里面的次数。
        EvaluateRecordEntity entity = evaluateRecordService.checkTimes(year, session, detail.getEmployeeIdCard(), detail.getEmployeeDepart(),
                detail.getRegulationTypeId(), detail.getRegulationDetailId());
        // 如果evaluate_record的次数为1，直接删去了，
        if (entity.getTimes() == 1) {
            // 直接删除全部记录。
            evaluateRecordService.deleteInfoById(entity.getId());
            List<String> employeeIdCards = toEmployeeService.selectIdCardsByRecordId(entity.getId());
            toEmployeeService.deleteInfoByRecordId(entity.getId());
            // 也应该删除这些员工的currentPerformanceData表的标注annotation
            currentPerformanceDataService.updateCurrentAnnotation(employeeIdCards);
            detailService.deleteRecordDetail(detail.getId());
            detailService.updateCurrentPerformanceData(employeeIdCards, null);
            return AjaxResult.success("删除数据成功！");
        }
        // 如果要删除的这条记录，肇事者犯过多次，大于最大次数，减去一次对关联人员扣减比例无影响。
        int maxTimes = timesService.maxTimesByDetailId(detail.getRegulationDetailId());
        entity.setTimes(entity.getTimes() - 1);
        if (entity.getTimes() >= maxTimes) {
            // 更新汇总表的次数.
            evaluateRecordService.updateByIdSelective(entity);
            detailService.deleteRecordDetail(detail.getId());
            return AjaxResult.success("删除数据成功！");
        }

        List<String> employeeIdCards = toEmployeeService.selectIdCardsByRecordId(entity.getId());
        // 如果肇事者违章次数小于最大次数且大于1，还需要更新关联人员的信息。
        toEmployeeService.deleteInfoByRecordId(entity.getId());
        evaluateRecordService.deleteInfoById(entity.getId());
        detailService.deleteRecordDetail(detail.getId());
        detailService.updateCurrentPerformanceData(employeeIdCards, null);
        // 还需要更新evaluate_record表和to_employee表里面的内容。
        entity.setId(null);
        boolean tag = insertToTable(entity, isManageTag);
        return AjaxResult.success("删除数据成功！");
    }

    private boolean insertToTable(EvaluateRecordEntity record, boolean isManageTag) {

        List<String> employeeIdCards = new ArrayList<>();
        boolean flag = true;
        System.out.println(record.getId());
        // 插入到evaluate_record表。
        int tag = evaluateRecordMapper.insertEvaluateRecord(record);
        System.out.println("tag："+tag);
        if (tag < 1) flag = false;
        // 将关联人员插入到evaluate_record_to_employee表中。
        int recordId = evaluateRecordMapper.selectCurrMaxEvaluateRecordKey();
        // 根据regulationDetailId和times找到每部分的扣减比例。
        RegulationTimes regulationTimes = regulationTimesMapper.selectByDetailIdAndTimes(record.getRegulationDetailId(), record.getTimes());
        EvaluateRecordToEmployee toEmployee = new EvaluateRecordToEmployee();
        EmployeeEntity employee = employeeMapper.selectByCard(record.getEmployeeIdCard());
        // 肇事者employee.
        if (regulationTimes.getPersonalProportion() > 0) {
            toEmployee.setEvaluateRecordId(recordId);
            toEmployee.setEmployeeIdCard(record.getEmployeeIdCard());
            toEmployee.setProportionOfPunishment(regulationTimes.getPersonalProportion());
            tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
            employeeIdCards.add(record.getEmployeeIdCard());
            if (tag < 1) flag = false;
            System.out.println("肇事者："+toEmployee.getEmployeeIdCard());
        }
        if (isManageTag) {
            detailService.updateCurrentPerformanceData(employeeIdCards, record);
            return flag;
        }
        if (employee.getTeamGroup() != null) {
            // 与肇事者同部门同班组
            if (regulationTimes.getTeamGroupProportion() > 0) {
                List<EmployeeEntity> related = employeeService.selectEmployeesByTeamGroup(employee.getTeamGroup().getId()+"", employee.getDepartment().getDepartmentId());
                if (related.size() > 0) {
                    for (EmployeeEntity rel:related) {
                        TeamGroup teamGroup = employeeService.selectById(employee.getTeamGroup().getId());
                        if (!rel.getIdCard().equals(employee.getIdCard()) && (teamGroup.getBranchManagerId() == null || !teamGroup.getBranchManagerId().equals(rel.getIdCard())) && (teamGroup.getMainManagerId() == null || !teamGroup.getMainManagerId().equals(rel.getIdCard())) ) {// 筛选同一个班组
                            // 如果分管或者主管与肇事者在一个班组，则不加。
                            toEmployee.setEvaluateRecordId(recordId);
                            toEmployee.setEmployeeIdCard(rel.getIdCard());
                            toEmployee.setProportionOfPunishment(regulationTimes.getTeamGroupProportion());
                            tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
                            employeeIdCards.add(rel.getIdCard());
                            if (tag < 1) flag = false;
                            System.out.println("同部门同班组："+toEmployee.getEmployeeIdCard());
                        }
                    }
                }
            }
            // 与肇事者同部门不同班组。
            if (regulationTimes.getDepartmentProportion() > 0) {
                List<EmployeeEntity> related = employeeService.selectEmployeesByDepartment(employee.getDepartment().getDepartmentId());
                if (related.size() > 0) {
                    for (EmployeeEntity rel:related) {
                        TeamGroup teamGroup = employeeService.selectById(employee.getTeamGroup().getId());
                        if (rel.getTeamGroup()== null || !rel.getTeamGroup().equals(employee.getTeamGroup())) {
                            if((teamGroup.getBranchManagerId() == null || !teamGroup.getBranchManagerId().equals(rel.getIdCard())) && (teamGroup.getMainManagerId() == null || !teamGroup.getMainManagerId().equals(rel.getIdCard()))) {
                                toEmployee.setEvaluateRecordId(recordId);
                                toEmployee.setEmployeeIdCard(rel.getIdCard());
                                toEmployee.setProportionOfPunishment(regulationTimes.getDepartmentProportion());
                                tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
                                employeeIdCards.add(rel.getIdCard());
                                if (tag < 1) flag = false;
                                System.out.println("同部门不同班组："+toEmployee.getEmployeeIdCard());
                            }
                        }
                    }
                }
            }
            // 肇事者的分管
            if (regulationTimes.getBranchManagerProportion() > 0) {
                TeamGroup teamGroup = employeeService.selectById(employee.getTeamGroup().getId());
                if (teamGroup.getBranchManagerId() != null) {
                    toEmployee.setEvaluateRecordId(recordId);
                    toEmployee.setEmployeeIdCard(teamGroup.getBranchManagerId());// 得到的是idCard。
                    toEmployee.setProportionOfPunishment(regulationTimes.getBranchManagerProportion());
                    tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
                    employeeIdCards.add(teamGroup.getBranchManagerId());
                    if (tag < 1) flag = false;
                    System.out.println("分管："+toEmployee.getEmployeeIdCard());
                }

            }
            // 肇事者的主管
            if (regulationTimes.getMainManagerProportion() > 0) {
                TeamGroup teamGroup = employeeService.selectById(employee.getTeamGroup().getId());
                if (teamGroup.getMainManagerId() != null) {
                    toEmployee.setEvaluateRecordId(recordId);
                    toEmployee.setEmployeeIdCard(teamGroup.getMainManagerId());
                    toEmployee.setProportionOfPunishment(regulationTimes.getMainManagerProportion());
                    tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
                    employeeIdCards.add(teamGroup.getMainManagerId());
                    if (tag < 1) flag = false;
                    System.out.println("主管："+toEmployee.getEmployeeIdCard());
                }

            }
            // 根据employeeIdCard找到关联人员。
            detailService.updateCurrentPerformanceData(employeeIdCards, record);
            return flag;
        }else {
            //当员工没有班组时，设置部门扣减比例
            if (regulationTimes.getDepartmentProportion() > 0) {
                List<EmployeeEntity> related = employeeService.selectEmployeesByDepartment(employee.getDepartment().getDepartmentId());
                if (related.size() > 0) {
                    for (EmployeeEntity rel:related) {
                        if(!rel.getIdCard().equals(employee.getIdCard())){
                            toEmployee.setEvaluateRecordId(recordId);
                            toEmployee.setEmployeeIdCard(rel.getIdCard());
                            toEmployee.setProportionOfPunishment(regulationTimes.getDepartmentProportion());
                            tag = toEmployeeMapper.insertEvaluateRecordToEmployee(toEmployee);
                            employeeIdCards.add(rel.getIdCard());
                            if (tag < 1) flag = false;
                            //System.out.println("没班组的员工的部门员工id:："+toEmployee.getEmployeeIdCard());
                        }
                    }
                }
            }
            detailService.updateCurrentPerformanceData(employeeIdCards, record);
            return flag;
        }
    }

    private String getQuarterStart(Date date) {
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(date);
        //get方法：获取给定日历属性的值，如 endCalendar.get(Calendar.MONTH) 获取日历的月份
        //计算季度数：由于月份从0开始，即1月份的Calendar.MONTH值为0,所以计算季度的第一个月份只需 月份 / 3 * 3
        startCalendar.set(Calendar.MONTH, (((int) startCalendar.get(Calendar.MONTH)) / 3) * 3);
        startCalendar.set(Calendar.DAY_OF_MONTH, 1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(startCalendar.getTime());
    }

    private String getQuarterEnd(Date date) {
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(date);
        //计算季度数：由于月份从0开始，即1月份的Calendar.MONTH值为0,所以计算季度的第三个月份只需 月份 / 3 * 3 + 2
        endCalendar.set(Calendar.MONTH, (((int) endCalendar.get(Calendar.MONTH)) / 3) * 3 + 2);
        endCalendar.set(Calendar.DAY_OF_MONTH, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(endCalendar.getTime());
    }
}
